home *** CD-ROM | disk | FTP | other *** search
- /*** analog 1.9beta ***/
- /* Please read Readme.html, or http://www.statslab.cam.ac.uk/~sret1/analog/ */
-
- /*** utils.c; lots of little functions to do odd little things ***/
-
- #include "analhea2.h"
-
- /* First, wildcard matching. This is restricted to at most one * (but any ?s).
- NB argument order and return value different from HP/UX fnmatch() */
-
- flag matchq(char *string, char *pattern, size_t n)
- { /* first, match with no *'s, up to n characters */
- flag answer;
-
- for(answer = TRUE; answer == TRUE &&
- (*string != '\0' || *pattern != '\0') && n > 0; n--) {
- answer = (*string == *pattern || *pattern == '?');
- string++;
- pattern++;
- }
-
- return(answer);
- }
-
- flag wildmatch(char *string, char *pattern, char **w1, char **w2)
- { /* w1 and w2 are changed to reflect part of string represented by * */
- char *c;
- flag answer;
-
- if ((c = strchr(pattern, '*')) == NULL) {
- *w1 = string;
- *w2 = string;
- return(matchq(string, pattern, INFINITY));
- }
- else {
- *c = '\0';
- *w1 = string + strlen(pattern);
- *w2 = string + MAX(strlen(string) - strlen(c + 1), 0);
- answer = (matchq(string, pattern, strlen(pattern))) &&
- (matchq(*w2, c + 1, INFINITY));
- *c = '*';
- return(answer);
- }
- }
-
- int strtomonth(char month[3]) /* convert 3 letter month abbrev. to int */
- {
- int monthno = ERR;
-
- switch (month[0]) {
- case 'A':
- switch (month[1]) {
- case 'p':
- monthno = 3;
- break;
- case 'u':
- monthno = 7;
- break;
- }
- break;
- case 'D':
- monthno = 11;
- break;
- case 'F':
- monthno = 1;
- break;
- case 'J':
- switch (month[1]) {
- case 'a':
- monthno = 0;
- break;
- case 'u':
- switch (month[2]) {
- case 'l':
- monthno = 6;
- break;
- case 'n':
- monthno = 5;
- break;
- }
- break;
- }
- break;
- case 'M':
- switch (month[2]) {
- case 'r':
- monthno = 2;
- break;
- case 'y':
- monthno = 4;
- break;
- }
- break;
- case 'N':
- monthno = 10;
- break;
- case 'O':
- monthno = 9;
- break;
- case 'S':
- monthno = 8;
- break;
- }
-
- return(monthno);
-
- }
-
- int dayofdate(int date, int monthno, int year) /* day of week of given date */
- {
- extern int dateoffset[];
-
- int x;
- x = dateoffset[monthno] + date + year + (year / 4) + 5 -
- ISLEAPJF(monthno, year);
- return(x % 7);
- }
-
- int minsbetween(int date1, int monthno1, int year1, int hr1, int min1,
- int date2, int monthno2, int year2, int hr2, int min2)
- {
- extern int dateoffset[];
-
- int x, y;
- x = dateoffset[monthno1] + date1 + year1 * 365 + (year1 / 4) -
- ISLEAPJF(monthno1, year1);
- y = dateoffset[monthno2] + date2 + year2 * 365 + (year2 / 4) -
- ISLEAPJF(monthno2, year2);
-
- return((y - x) * 1440 + (hr2 - hr1) * 60 + (min2 - min1));
- }
-
- long timecode(int date, int monthno, int year, int hr, int min)
- { /* calculate a 'timecode', i.e. increasing function of time */
-
- return((year - 1990) * 535680 + /* 60 * 24 * 31 * 12 */
- monthno * 44640 +
- date * 1440 +
- hr * 60 +
- min);
- }
-
- struct timestruct startofweek(struct timestruct atime)
- { /* given a time, what is the time at the start of that week? */
-
- extern int monthlength[];
-
- extern int weekbeginson;
-
- struct timestruct answer;
- int day;
-
- day = dayofdate(atime.date, atime.monthno, atime.year);
-
- answer.date = atime.date - day + weekbeginson;
- /* giving a weekbeginson-day in [date - 6, date + 6] */
- if (answer.date > atime.date)
- answer.date -= 7;
- answer.monthno = atime.monthno;
- answer.year = atime.year;
-
- if (answer.date <= 0) {
- answer.monthno--;
- if (answer.monthno == -1) {
- answer.monthno = 11;
- answer.year--;
- }
- answer.date = monthlength[answer.monthno] + answer.date +
- ISLEAPFEB(answer.monthno, answer.year);
- }
-
- answer.code = timecode(answer.date, answer.monthno, answer.year,
- answer.hr = 0, answer.min = 0);
-
- return(answer);
-
- }
-
- FILE *fopenlog(char *name, char logtype[12], flag *ispipe)
- { /* open a logfile with a particular name for reading */
-
- extern char commandname[];
- extern struct loglist *uncompresshead;
- extern flag warnq;
-
- FILE *f;
- struct loglist *uncompressp;
- char *w1, *w2;
- char command[MAXSTRINGLENGTH];
-
- *ispipe = OFF;
-
- if (STREQ(name, "stdin"))
- f = stdin;
- else {
- f = fopen(name, "r");
- if (f == NULL) {
- if (warnq)
- fprintf(stderr, "%s: Warning: Failed to open %s %s: ignoring it\n",
- commandname, logtype, name);
- }
- else for (uncompressp = uncompresshead; uncompressp -> name[0] != '\0' &&
- !(*ispipe); uncompressp = uncompressp -> next) {
- if (wildmatch(name, uncompressp -> name, &w1, &w2)) {
- fclose(f);
- strcpy(command, uncompressp -> prefix);
- strcat(command, " ");
- strcat(command, name);
- f = popen(command, "r");
- *ispipe = ON;
- }
- }
- }
-
- return(f);
- }
-
- int fcloselog(FILE *f, char *name, char logtype[12], flag ispipe)
- { /* close it again */
-
- extern char commandname[];
- extern flag warnq;
-
- int rc;
-
- if (!ispipe)
- rc = fclose(f); /* Not much can go wrong with fclose. I hope. */
- else if ((rc = pclose(f)) != 0 && warnq)
- fprintf(stderr, "%s: Warning: Problems uncompressing %s %s\n",
- commandname, logtype, name);
-
- return(rc);
- }
-
- void int3printf(FILE *outf, int x)
- /* print +ve integer with separators every 3 digits */
- {
- extern char sepchar;
-
- int i = 1;
-
- if (sepchar == '\0')
- fprintf(outf, "%d", x);
-
- else {
- while (x / 1000 >= i) /* i * 1000 might overflow */
- i *= 1000; /* find how big x is, so we know where to start */
-
- fprintf(outf, "%d", (x / i) % 1000);
- /* now run down again, printing each clump */
-
- for ( i /= 1000; i >= 1; i /= 1000)
- fprintf(outf, "%c%03d", sepchar, (x / i) % 1000);
- }
- }
-
- void double3printf(FILE *outf, double x)
- /* the same, only with +ve integer doubles */
- {
- extern char sepchar;
-
- int i = 0;
-
- if (x < 0.5)
- fprintf(outf, "0");
-
- else if (sepchar == '\0')
- fprintf(outf, "%.0f", x);
-
- else {
-
- while (x >= 1000) {
- x /= 1000;
- i++;
- }
-
- fprintf(outf, "%d", (int)ROUND(x));
-
- for ( ; i >= 1; i--) {
- x -= (int)x;
- x *= 1000;
- fprintf(outf, "%c%03d", sepchar, (int)ROUND(x));
- }
-
- }
-
- }
-
- void doublefprintf(FILE *outf, double x)
- { /* print a double in %f format without trailing zeros */
- int prec;
- double d;
-
- /* first calculate how many decimal places we need */
-
- d = x;
- for (prec = 0; d - floor(d + 0.000005) > 0.00001; prec++)
- d *= 10;
-
- /* now print it */
-
- fprintf(outf, "%.*f", prec, x);
- }
-
- void *xmalloc(size_t size)
- { /* the same as malloc, only checks for out of memory */
-
- extern char commandname[];
- extern flag sq;
-
- void *answer;
-
- if ((answer = malloc(size)) == NULL) {
- fprintf(stderr, "%s: Ran out of memory: cannot continue\n", commandname);
- if (sq == ON)
- fprintf(stderr, " Try turning hostname counting off or using approximate host counting");
- exit(ERR);
- }
-
- else
- return(answer);
- }
-
- void *xcalloc(int nelem, int elsize)
- { /* ditto calloc */
-
- extern char commandname[];
- extern flag sq;
-
- void *answer;
-
- if ((answer = calloc((size_t)nelem, (size_t)elsize)) == NULL) {
- fprintf(stderr, "%s: Ran out of memory: cannot continue\n", commandname);
- if (sq == ON)
- fprintf(stderr, " Try turning hostname counting off or using approximate host counting");
- exit(ERR);
- }
-
- else
- return(answer);
- }
-
- char *strtolower(char *string)
- { /* convert a string to lower case */
-
- char *c;
-
- for (c = string; *c != '\0'; c++)
- *c = tolower(*c);
-
- return(string);
- }
-
- char *strtoupper(char *string)
- { /* convert a string to upper case */
-
- char *c;
-
- for (c = string; *c != '\0'; c++)
- *c = toupper(*c);
-
- return(string);
- }
-
- int magicno(char *string, int base)
- { /* convert a string to a magic number (using c_i.2^i mod b) */
-
- int answer;
- int i;
-
- answer = 0;
- for (i = 0; string[i] != '\0'; i++) {
- answer += answer + string[i];
- if (answer < 0)
- answer = -answer;
- while (answer >= base)
- answer -= base;
- }
-
- return(answer);
- }
-
- int hoststrcmp(char *hostn1, char *hostn2)
- { /* given two reversed hostnames, what is their "alphabetical" order? */
-
- char hostn1cpy[MAXSTRINGLENGTH], hostn2cpy[MAXSTRINGLENGTH];
- char *part11, *part12, *part13, *part14, *part2;
- int tempint1, tempint2;
-
- if (!isdigit(*hostn1)) {
- if (isdigit(*hostn2))
- return(-1); /* all numbers come after all letters */
- else
- return(strcmp(hostn1, hostn2)); /* both non-numbers; usual alphabet */
- }
- else if (!isdigit(*hostn2))
- return(1);
- else {
- /* the difficult case; both numerical. Convert bits to numbers */
- strcpy(hostn1cpy, hostn1); /* because strtok destroys the string */
- strcpy(hostn2cpy, hostn2);
- part11 = strtok(hostn1cpy, ".");
- part12 = strtok((char *)NULL, ".");
- part13 = strtok((char *)NULL, ".");
- part14 = strtok((char *)NULL, ".");
-
- part2 = strtok(hostn2cpy, ".");
- tempint1 = atoi(part11);
- tempint2 = atoi(part2);
- if (tempint1 != tempint2)
- return(tempint1 - tempint2);
- else {
- part2 = strtok((char *)NULL, ".");
- if (part12 == NULL && part2 == NULL)
- return(0);
- else if (part12 == NULL)
- return(-999);
- else if (part2 == NULL)
- return(999);
- else {
- tempint1 = atoi(part12);
- tempint2 = atoi(part2);
- if (tempint1 != tempint2)
- return(tempint1 - tempint2);
- else {
- part2 = strtok((char *)NULL, ".");
- if (part13 == NULL && part2 == NULL)
- return(0);
- else if (part13 == NULL)
- return(-999);
- else if (part2 == NULL)
- return(999);
- else {
- tempint1 = atoi(part13);
- tempint2 = atoi(part2);
- if (tempint1 != tempint2)
- return(tempint1 - tempint2);
- else {
- part2 = strtok((char *)NULL, ".");
- if (part14 == NULL && part2 == NULL)
- return(0);
- else if (part14 == NULL)
- return(-999);
- else if (part2 == NULL)
- return(999);
- else {
- tempint1 = atoi(part14);
- tempint2 = atoi(part2);
- if (tempint1 != tempint2)
- return(tempint1 - tempint2);
- else
- return(0);
- }
- }
- }
- }
- }
- }
- }
- }
-